package com.tqz.juc.aqs;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 使用 {@link CountDownLatch} 模拟百米赛跑.
 *
 * @author tianqingzhao
 * @since 2022/2/5 18:22
 */
public class CountdownLatchTest2 {

    public static void main(String[] args) {
        ExecutorService service = Executors.newCachedThreadPool();

        // 裁判1个
        final CountDownLatch cdOrder = new CountDownLatch(1);
        // 运动员4个
        final CountDownLatch cdAnswer = new CountDownLatch(4);

        for (int i = 0; i < 4; i++) {
            Runnable runnable = () -> {
                try {
                    System.out.println("选手" + Thread.currentThread().getName() + "正在等待裁判发布口令");

                    // 等待裁判吹哨
                    cdOrder.await();
                    System.out.println("选手" + Thread.currentThread().getName() + "已接受裁判口令");

                    Thread.sleep((long) (Math.random() * 10000));
                    System.out.println("选手" + Thread.currentThread().getName() + "到达终点");

                    // 跑到终点，计数器减1
                    cdAnswer.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            };
            service.execute(runnable);
        }

        try {
            // 运动员等待裁判吹哨
            Thread.sleep(3000);
            System.out.println("裁判" + Thread.currentThread().getName() + "即将发布口令");

            // 裁判吹哨，计数器减1
            cdOrder.countDown();
            System.out.println("裁判" + Thread.currentThread().getName() + "已发送口令，正在等待所有选手到达终点");

            // 等待所有选手到达终点
            cdAnswer.await();
            System.out.println("所有选手都到达终点");
            System.out.println("裁判" + Thread.currentThread().getName() + "汇总成绩排名");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        service.shutdown();
    }
}
